/* 
 * File:   Utiles.h
 * Author: Gabriel Fainstein
 *
 * Created on 19 de mayo de 2013, 19:30
 */

#ifndef UTILES_H
#define	UTILES_H

#include <stdint.h>
#include <list>
#include <string>
#include <dirent.h>
#include <sys/stat.h>
#include <vector>
#include "common_Excepcion.h"

using namespace std;
using namespace TP;

typedef std::vector<std::string> LNombreArchivo;
typedef std::vector<std::string> LPathArchivo;

namespace TP { namespace Archivos { 
/**
 * @class FileUtils
 * Diferentes utilidades para manejar directorios y archivos del SO
 */
class FileUtils {
    
    public:
        static const unsigned int bytesPorChunk;
        
        FileUtils();
        
        /**
         * @brief dado un path devuelve una lista con los nombres de los 
         * archivos que se encuentran en dicho directorio
         * @param path Directorio de donde se quieren obtener los nombre de 
         * archivos
         * @param l lista de nombre de archivos del directorio
         * @return true en caso de exito, false si hubo problemas con el 
         * directorio. 
         */
        bool ObtenerNombreArchivos(const std::string & path, 
                                   LNombreArchivo & l)  const;

        /**
         * @brief dado un path devuelve una lista con el full path de cada 
         * archivo que se encuentre en dicho directorio
         * @param path Directorio de donde se quieren obtener los archivos
         * @param l lista de full path de archivos del directorio
         * @return true en caso de exito, false si hubo problemas con el 
         * directorio.
         */
        bool ObtenerFullPathArchivo(const std::string & path, 
                                      LPathArchivo & l) const;

        /**
         * @brief dado un path, devuelve true si es un directorio existente, 
         * false en caso contrario
         * @param path Directorio que se quiere chequear su existencia
         * @return true si existe el directorio, false si no existe
         */
        bool DirectorioExistente(const std::string & path);

        /**
         * @brief Devuelve el chunk de datos correspondiente indicado por 
         * numero de chunk y el full path del archivo 
         * @param pData array de bytes del chunk
         * @param pDataLongitud longitud del chunk
         * @param pRutaCompletaArchivo Ruta completa del archivo
         * @param pNumeroChunk Numero de chunk que se desea obtener
         * @return VOID
         */
        void ComputarChunk(uint8_t* &pData, size_t &pDataLongitud, const std::string& pRutaCompletaArchivo, unsigned int pNumeroChunk);
        
        /**
         * @brief Intenta crear un nuevo directorio, representado por 'path'.
         * @param path Directorio a crear
         * @return true en caso exitoso, false si no es exitoso
         */
        bool CrearDirectorio(const std::string& path);
        
        /**
         * @brief Intenta crear un nuevo archivo
         * @param pRutaCompletaArchivo Ruta completa del archivo a crear
         * @return true si se creó exitosamente, false si no se creó
         */
        bool CrearArchivo (const string &pRutaCompletaArchivo);

        /**
         * @brief Obtener el tamaño de bytes de un path
         * @param path Directorio a analizar
         * @return Tamaño en bytes de un path, -1 si hay errores
         */
        double GetPathSize(const std::string& path);
        
        /**
         * @brief Obtener la cantidad de chunks de un archivo determinado
         * @param pRutaCompletaArchivo ruta completa del archivo a analizar
         * @return cantidad de chunks del archivo
         */
        size_t CalcularCantidadChunks(const string &pRutaCompletaArchivo);
        
        /**
         * @brief Obtiene el hash de un chunk de bytes de un archivo
         * @param pRutaCompletaArchivo ruta completa del archivo a analizar
         * @param pIndiceChunk numero de chunk a hashear
         * @return hash del chunk
         */
        string GetHash (const string& pRutaCompletaArchivo, const size_t pIndiceChunk);
        /**
         * @brief Verifica la existencia de un archivo
         * @param pRutaCompletaArchivo ruta completa del archivo a analizar
         * @return true si existe, false si no existe
         */
        bool ArchivoExistente (const string & pRutaCompletaArchivo);
        
    private:
        
        FileUtils(const FileUtils&);
        
        FileUtils& operator=(const FileUtils&);       
};

}}


#endif	/* UTILES_H */

